package com.example.easydownloadback.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.easydownloadback.domin.*;
import com.example.easydownloadback.mapper.UserMapper;
import com.example.easydownloadback.service.UserService;
import com.example.easydownloadback.util.Code;
import com.example.easydownloadback.util.RedisPrefix;
import com.example.easydownloadback.util.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ResponseResult<String> login(LoginFormDTO loginForm) {
        User userSelect = query().eq("username", loginForm.getUsername()).one();
        // 根据用户名查不到用户说明用户名不存在
        if (userSelect == null) {
            return new ResponseResult<>(Code.error, "用户名或密码错误！");
        }
        // 通过盐值 + 登录密码获取加密后密码
        String md5Pass = DigestUtil.md5Hex(loginForm.getPassword() + userSelect.getSalt());
        // 如果密码和查询出来的用户不同
        if (!md5Pass.equals(userSelect.getPassword())) {
            return new ResponseResult<>(Code.error, "用户名或密码错误！");
        }
        // 这里说明验证成功
        // 生成token
        String token = UUID.randomUUID().toString(true);
        UserDTO userDTO = BeanUtil.copyProperties(userSelect, UserDTO.class);
        // 将User转换为Hash存储
        Map<String, Object> map = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create().
                        // 按照要求映射，值统一toString
                                setFieldValueEditor((filedName, filedValue) -> {
                                    if (filedValue == null) {
                                        return null;
                                    } else {
                                        return filedValue.toString();
                                    }
                                }));
        // 存储
        String tokenKey = RedisPrefix.LOGIN_USER_KEY + token;
        // 这里不使用put是防止频繁的与redis交互，所以使用putAll（需要先将bean转换为Map）
        stringRedisTemplate.opsForHash().putAll(tokenKey, map);
        // 设置key有效期
        stringRedisTemplate.expire(tokenKey, RedisPrefix.LOGIN_USER_TTL, TimeUnit.MINUTES);
        // 返回token
        return new ResponseResult<>(Code.success, "登录成功！",token);
    }

    @Override
    public ResponseResult logout(String token) {
        String tokenKey = RedisPrefix.LOGIN_USER_KEY + token;
        stringRedisTemplate.delete(tokenKey);
        return new ResponseResult<>(Code.success, "退出登录成功！");
    }

    @Override
    public ResponseResult password(PasswordFormDTO passwordFormDTO) {
        UserDTO user = UserHolder.getUser();
        User userById = query().eq("id", user.getId()).one();
        String oldMd5Pass = DigestUtil.md5Hex(passwordFormDTO.getOldPassword() + userById.getSalt());
        if (!userById.getPassword().equals(oldMd5Pass)) {
            return new ResponseResult<>(Code.service_error, "原密码不正确！");
        }
        String newMd5Pass = DigestUtil.md5Hex(passwordFormDTO.getNewPassword() + userById.getSalt());
        boolean update = update().set("password", newMd5Pass).eq("id", user.getId()).update();
        if (update) {
            return new ResponseResult<>(Code.success, "修改密码成功！");
        } else {
            return new ResponseResult<>(Code.error, "系统异常！");
        }
    }
}
